package com.project_doctor.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project_doctor.mapper.HealthMapper;
import com.project_doctor.mapper.TagMapper;
import com.project_doctor.pojo.Health;
import com.project_doctor.pojo.Resident;
import com.project_doctor.pojo.Tag;
import com.project_doctor.pojo.dto.DetailsDTO;
import com.project_doctor.pojo.dto.ResidentSearchDTO;
import com.project_doctor.pojo.dto.ResidentTagDTO;
import com.project_doctor.pojo.ResidentTagItem;
import com.project_doctor.pojo.vo.ResidentVO;
import com.project_doctor.service.ResidentService;
import com.project_doctor.mapper.ResidentMapper;
import com.project_doctor.mapper.PackageMapper;
import com.project_doctor.pojo.Package;
import com.project_doctor.mapper.TeamMapper;
import com.project_doctor.pojo.Team;
import com.project_doctor.mapper.InstitutionMapper;
import com.project_doctor.pojo.Institution;
import com.project_doctor.service.TagService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
import java.awt.RenderingHints;

import static cn.hutool.core.date.DateTime.now;

/**
* @author xixif
* @description 针对表【t_resident(居民基本信息表)】的数据库操作Service实现
* @createDate 2025-06-03 16:14:08
*/
@Service
public class ResidentServiceImpl extends ServiceImpl<ResidentMapper, Resident>
    implements ResidentService{
    @Autowired
    private ResidentMapper residentMapper;

    @Autowired
    private TagMapper tagMapper;

    @Autowired
    private HealthMapper healthMapper;

    @Autowired
    private PackageMapper packageMapper;

    @Autowired
    private TeamMapper teamMapper;

    @Autowired
    private InstitutionMapper institutionMapper;

    @Autowired
    private TagService tagService;

    @Override
    public Page<ResidentTagDTO> getResident(Integer pageNum, Integer pageSize, ResidentSearchDTO searchDTO) {
        Page<ResidentTagDTO> page = new Page<>(pageNum, pageSize);
        List<ResidentTagDTO> residents = residentMapper.selectResidents(page, searchDTO);

        List<Long> ids = residents.stream().map(ResidentTagDTO::getId).collect(Collectors.toList());

        if (ids.isEmpty()) {
            page.setRecords(Collections.emptyList());
            return page;
        }

        List<ResidentTagItem> tagItems = residentMapper.selectResidentTags(ids);

        Map<Long, List<String>> tagMap = tagItems.stream()
                .collect(Collectors.groupingBy(
                        ResidentTagItem::getResidentId,
                        Collectors.mapping(ResidentTagItem::getTagName, Collectors.toList())
                ));

        for (ResidentTagDTO resident : residents) {
            resident.setTag(tagMap.getOrDefault(resident.getId(), Collections.emptyList()));
        }

        page.setRecords(residents);
        return page;
    }

    @Override
    @Transactional
    public void addResident(ResidentTagDTO residentTagDTO) {
        Resident resident = new Resident();
        BeanUtils.copyProperties(residentTagDTO, resident);
        resident.setAvatar("avatar.jpg");
        residentMapper.insert(resident);

        Long residentId = resident.getId();
        if (residentTagDTO.getTag() != null && !residentTagDTO.getTag().isEmpty()) {
            // System.out.println("有值有值有值有值");
            List<Tag> tags = residentTagDTO.getTag().stream().map(tagName -> {
                Tag tag = new Tag();
                tag.setRefId(residentId);
                tag.setRefType(1);
                tag.setName(tagName);
                tag.setAddedBy("admin");
                return tag;
            }).collect(Collectors.toList());
            tagMapper.insertBatch(tags);
        }

        if (residentTagDTO.getHealth() != null) {
            Health health = new Health();
            BeanUtils.copyProperties(residentTagDTO.getHealth(), health);
            health.setResidentId(residentId);
            healthMapper.insert(health);
        }
    }


    @Override
    public Long getResidentId() {
        Long maxId = residentMapper.selectResidentId();
        return maxId;
    }

    @Override
    public ResidentTagDTO getResidentById(Long id) {
        ResidentTagDTO dto = residentMapper.selectResidentById(id);

        List<ResidentTagItem> tagItems = residentMapper.selectResidentTags(Collections.singletonList(id));
        List<String> tags = tagItems.stream().map(ResidentTagItem::getTagName).collect(Collectors.toList());
        dto.setTag(tags);

        if (dto.getHealth() == null) {
            dto.setHealth(new Health());
        }

        return dto;
    }

    @Override
    @Transactional
    public void updateResident(ResidentTagDTO residentTagDTO) {
        Resident resident = new Resident();
        BeanUtils.copyProperties(residentTagDTO, resident);
        residentMapper.updateById(resident);

        LambdaQueryWrapper<Tag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tag::getRefId, residentTagDTO.getId());
        List<Tag> tags1 = tagMapper.selectList(wrapper);
        if (tags1 != null) {
            tagMapper.delete(wrapper);
        }

        if (residentTagDTO.getTag() != null && !residentTagDTO.getTag().isEmpty()) {
            List<Tag> tags = residentTagDTO.getTag().stream().map(tagName -> {
                Tag tag = new Tag();
                tag.setRefId(resident.getId());
                tag.setRefType(1);
                tag.setAddedBy("admin");
                tag.setName(tagName);
                return tag;
            }).collect(Collectors.toList());
            tagMapper.insertBatch(tags);
        }

        if (residentTagDTO.getHealth() != null) {
            Health health = new Health();
            BeanUtils.copyProperties(residentTagDTO.getHealth(), health);
            health.setResidentId(resident.getId());


            LambdaQueryWrapper<Health> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(Health::getResidentId,  resident.getId());
            Health health1 = healthMapper.selectOne(wrapper1);
            if (health1 != null) {
                health.setId(health1.getId());
                healthMapper.updateById(health);
            } else {
                healthMapper.insert(health);
            }
        }
    }

    @Override
    public void deleteResident(Long id) {
        residentMapper.deleteById(id);

        LambdaQueryWrapper<Tag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tag::getRefId, id);
        tagMapper.delete(wrapper);

        LambdaQueryWrapper<Health> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Health::getResidentId, id);
        healthMapper.delete(wrapper1);
    }

    @Override
    public List<Package> getAllPackages() {
        return packageMapper.getAllPackages();
    }

    @Override
    public List<Team> getAllTeams() {
        return teamMapper.getAllTeams();
    }

    @Override
    public List<Institution> getAllInstitutions() {
        return institutionMapper.getAllInstitutions();
    }

    @Override
    public String generateResidentInfoImage(Long id) {
        ResidentTagDTO info = getResidentById(id);
        String fileName = "resident_info_" + id + ".png";
        String imageDir = "D:/WebCode/project/project_doctor/public/images/";
        File dir = new File(imageDir);
        if (!dir.exists()) dir.mkdirs();
        String filePath = imageDir + fileName;
        int width = 480, height = 650;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        // 抗锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 背景
        g.setColor(new Color(245, 247, 250));
        g.fillRoundRect(0, 0, width, height, 32, 32);
        // 卡片白底
        g.setColor(Color.WHITE);
        g.fillRoundRect(24, 24, width-48, height-48, 24, 24);
        // 阴影（简单模拟）
        g.setColor(new Color(220,220,220));
        g.drawRoundRect(24, 24, width-48, height-48, 24, 24);
        // 标题
        g.setColor(new Color(51,51,51));
        g.setFont(new Font("微软雅黑", Font.BOLD, 32));
        String title = "居民信息卡";
        int titleWidth = g.getFontMetrics().stringWidth(title);
        g.drawString(title, (width-titleWidth)/2, 80);
        // 分隔线
        g.setColor(new Color(230,230,230));
        g.fillRect(48, 100, width-96, 2);
        // 字段内容
        g.setFont(new Font("微软雅黑", Font.PLAIN, 22));
        int y = 140, line = 38;
        String[][] fields = {
            {"姓名", info.getName()},
            {"年龄", info.getAge()==null?"":info.getAge().toString()},
            {"电话", info.getPhone()},
            {"身份证", info.getIdCard()},
            {"现居地址", info.getAddress()},
            {"籍贯", info.getOriginPlace()},
            {"民族", info.getNation()},
            {"性别", info.getGender()!=null?(info.getGender()==1?"男":info.getGender()==0?"女":""):""},
            {"职业", info.getOccupation()}
        };
        if (info.getHealth()!=null) {
            fields = java.util.Arrays.copyOf(fields, fields.length+3);
            fields[fields.length-3] = new String[]{"身高", info.getHealth().getHeight()==null?"":info.getHealth().getHeight().toString()};
            fields[fields.length-2] = new String[]{"体重", info.getHealth().getWeight()==null?"":info.getHealth().getWeight().toString()};
            fields[fields.length-1] = new String[]{"血型", info.getHealth().getBloodType()==null?"":info.getHealth().getBloodType()};
        }
        for (String[] field : fields) {
            g.setColor(new Color(80,80,80));
            g.drawString(field[0]+"：", 60, y);
            g.setColor(new Color(32, 99, 195));
            g.drawString(field[1]==null?"":field[1], 160, y);
            y += line;
            // 分隔线
            g.setColor(new Color(240,240,240));
            g.fillRect(48, y-24, width-96, 1);
        }
        // 底部说明
        g.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        g.setColor(new Color(180,180,180));
        g.drawString("蜗牛家庭医生", width-180, height-30);
        g.dispose();
        try {
            ImageIO.write(image, "png", new File(filePath));
        } catch (IOException e) {
            return "";
        }
        // 公网/images/目录映射到public/images/
        return "http://671c647c.r16.cpolar.top/images/" + fileName;
    }

    @Override
    public List<Resident> getResident() {
        LambdaQueryWrapper<Resident> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Resident::getId, Resident::getName);
        return residentMapper.selectList(wrapper);
    }

    @Override
    @Transactional
    public void updateService(DetailsDTO dto) {
// 获取 DTO 中的 birthDate（Date 类型）
        Date birthDate = dto.getBirthDate();
        if (birthDate != null) {
            // 将 Date 转换为 LocalDate
            LocalDate birthLocalDate = birthDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate currentLocalDate = LocalDate.now();

            // 计算年龄
            Period period = Period.between(birthLocalDate, currentLocalDate);
            int age = period.getYears();
            dto.setAge(age); // 设置年龄到 DTO
        }

// 构建更新Wrapper
        LambdaUpdateWrapper<Resident> residentWrapper = new LambdaUpdateWrapper<>();
        residentWrapper.eq(Resident::getId, dto.getResidentId())
                .set(Resident::getIdCard, dto.getIdCard())
                .set(Resident::getGender, dto.getGender())
                .set(Resident::getBirthdate, dto.getBirthDate()) // 传入 Date 类型
                .set(Resident::getAge, dto.getAge()) // 显式更新年龄
                .set(Resident::getPhone, dto.getPhone())
                .set(Resident::getAddress, dto.getAddress());

        residentMapper.update(null, residentWrapper);
        if (dto.getTags() != null){

            List<String> tags = tagService.selectTagsList(dto.getResidentId());

            if(tags!=null){
                tagService.deleteTags(dto.getResidentId());
            }
            for (String tag : dto.getTags()){
                Tag tagData = new Tag();
                tagData.setRefId(dto.getResidentId().longValue());
                tagData.setRefType(1);
                tagData.setName(tag);
                tagData.setAddedBy(dto.getUserName());
                tagData.setLastModified(now());
                tagService.insertTags(tagData);
            }
        }
    }

    @Override
    public ResidentVO selectResident(Integer residentId) {
        LambdaQueryWrapper<Resident> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resident::getId,residentId);
        Resident resident = residentMapper.selectOne(wrapper);
        ResidentVO residentVO = new ResidentVO();
        residentVO.setResidentId(resident.getId());
        residentVO.setResidentName(resident.getName());
        residentVO.setIdCard(resident.getIdCard());
        residentVO.setPhone(resident.getPhone());
        residentVO.setAddress(resident.getAddress());
        residentVO.setGender(resident.getGender());
        residentVO.setBirthDate(resident.getBirthdate());
//        residentVO.setAge(resident.getAge());
        residentVO.setTags(tagService.selectTagsList(residentId));
        return residentVO;
    }
}




